#include <atomic>
#include <chrono>
#include <any>
#include <deque>
#include <optional>
#include <ostream>
#include <string>
#include <unordered_map>
#include <iostream>
#include <memory>
#include <vector>

class MsgFields {
public:
    template<typename T>
    auto get(const std::string &key, T default_value = T()) const -> T {
        auto it = fields_.find(key);
        if (it == fields_.end()) {
            return default_value;
        }
        try {
            return std::any_cast<T>(it->second);
        } catch (std::bad_any_cast &e) {
            std::cout << "cast failed for key: " << key << ", error: " << e.what() << std::endl;
            return default_value;
        }
    }
    template<typename T>
    void add(const std::string &key, T value) {
        fields_[key] = value;
    }
    void add(const std::string &key, const char *value) {
        fields_[key] = std::string(value);
    }
    bool empty() const {
        return fields_.empty();
    }
private:
    std::unordered_map<std::string, std::any> fields_;
};
int main() {
    std::cout << "Hello ";
#ifdef ARCH_
    std::cout << "arch is "
#if ARCH_ == aarch64
              << "aarch64"
#elif ARCH_ == x86_64
              << "x86_64"
#else
              << "unknown"
#endif
              << ", ";
#endif

#ifdef OS_
    std::cout << "OS is "
#if OS_ == qnx_qcom
              << "qnx_qcom"
#elif OS_ == qnx_driveos
              << "qnx_driveos"
#elif OS_ == android_qcom
              << "android_qcom"
#elif OS_ == linux_cuda
              << "linux_cuda"
#else
              << "unknown"
#endif
              << ", ";
#endif

#ifdef SOC_
    std::cout << "SOC is "
#if SOC_ == s8155
              << "s8155"
#elif SOC_ == s8255
              << "s8255"
#elif SOC_ == android_qcom
              << "android_qcom"
#elif SOC_ == orin
              << "orin"
#elif SOC_ == xavier
              << "xavier"
#else
              << "unknown"
#endif
              << std::endl;
#endif

    MsgFields fields;
    fields.add("id", 1);
    fields.add("name", "guoshunwu");
    fields.add("gender", true);

    fields.add("array", std::vector<int>{1, 2, 3});
    fields.add("map", std::unordered_map<std::string, int>{{"a", 1}, {"b", 2}});

    std::cout << "name = " << fields.get("name", std::string("unknown"))  << ", id: " << fields.get("id", -1) << std::endl;
    auto arr = fields.get<std::vector<int>>("array");
    auto map = fields.get<std::unordered_map<std::string, int>>("map");

    std::cout << "array = " << " size: " << arr.size() << std::endl;

    std::optional<int> a=1;
    a = std::nullopt;
    std::cout << "a = " << a.value_or(0)<< std::endl;

}
